# from gevent import monkey
# monkey.patch_all()
import os
import random
import re
import sys

import telnetlib
import time
import traceback
from datetime import datetime
from dateutil.relativedelta import relativedelta
from django.db import close_old_connections
from models.models import OltInfo, BoardInfo, SnBlacklist
from AutoRegister.settings import LOG_DIR
from omp.models import OmpDevice
from tools.Robot import sendTeam
from tools.redis import redisPool
from tools.tools import Save_OntRecord, write_log

# 初始化redis连接
redis_oper = redisPool()


class telnetip(object):
    def __init__(self, tnip, tnport, username, password, user_timestamp=None):
        close_old_connections()
        self.tn = telnetlib.Telnet()
        self.tnip = tnip
        # self.tnip = "10.10.10.201"
        self.tnport = int(tnport)
        self.username = username
        self.password = password
        self.user_timestamp = user_timestamp
        self.onu_set = set()
        try:
            self.olt_id = OltInfo.objects.get(olt_ip=self.tnip, olt_port=self.tnport).olt_id
        except Exception as e:
            print("获取self.olt_id 报错：%s" % str(e))
            self.olt_id = 0
        print("%s:%s self.olt_id: %s" % (self.tnip, self.tnport, self.olt_id))
        # self.olt_id = 1

    def login_host(self, userrole=None, time_out=None):
        close_old_connections()
        """
        return  timeout 连接超时
                userrole  user 用户登录  or  is None 系统登录
        """
        if time_out is None:
            time_out = 10

        # 用户启动OLT
        if userrole == "user":
            up_down_remind = "false"
            try:
                self.tn.open(self.tnip, self.tnport, timeout=time_out)
            except Exception as e:
                print('e==>', e)
                return False, "无法连接 %s:%s" % (self.tnip, self.tnport)

        # 正常启动OLT
        else:
            if self.olt_id == 0:
                print("发送微信，IP和端口不存在，无法登陆OLT")
                msg = "找不到 %s:%s OLT相关数据,无法登陆" % (self.tnip, self.tnport)
                # 发送微信 不携带wechat_group参数 默认发送到 CASE_GROUP_NAME
                sendTeam(msg, 'robot')
                # 运行日志 和 错误日志 # data, oltip, oltport, level=None
                write_log(msg, self.tnip, self.tnport, userrole, 'error')
                # userrole=userrole,
                return False, msg
            # 连接Telnet服务器
            print("connecting to {}:{}".format(self.tnip, self.tnport))

            up_down_remind = OltInfo.objects.get(olt_id=self.olt_id).up_down_remind
            print("up_down_remind", up_down_remind)
            while True:
                try:
                    self.tn.open(self.tnip, self.tnport, timeout=time_out)
                except Exception as e:
                    # 网络不通，发送信息
                    print("发送微信,无法连接%s:%s OLT : %s" % (self.tnip, self.tnport, e))

                    olt_info_obj = OltInfo.objects.get(olt_id=self.olt_id)
                    olt_name = olt_info_obj.olt_name
                    wechat_group = olt_info_obj.remind_group
                    msg = "[{}]登陆异常\n负责人请注意\n- IP:{}\n- 时间:{}\n登陆失败！！！".format(olt_name, self.tnip,
                                                                               str(datetime.now())[:19])
                    if olt_info_obj.up_down_remind == "是":
                        # 意外退出，是否发送信息的标记
                        sendmsg_swich = redis_oper.conn.get("%s_%s_sendmsg_swich" % (self.tnip, self.tnport))
                        if sendmsg_swich is None:
                            # 发送微信
                            # sendTeam(msg, 'robot')
                            pass

                    # 添加已经发送掉线信息的信号
                    redis_oper.conn.set("%s_%s_sendmsg_swich" % (self.tnip, self.tnport), "send")

                    # 运行日志 和 错误日志 data, oltip, oltport, level=None
                    write_log(traceback.format_exc(), self.tnip, self.tnport, level="error")
                    # write_log(data=traceback.format_exc(), oltip=self.tnip, oltport=self.tnport,

                    runstate = redis_oper.redis_get("%s_%s_runstate" % (self.tnip, self.tnport))
                    if runstate == "false":
                        return False, "OLT处于连接失败状态，用户执行退出"

                    # 代表OLT已经启动 ，但是 是否启动成功 不一定
                    redis_oper.conn.set("%s_%s_runstate" % (self.tnip, self.tnport), "true")

                    # 人为操作  启动运行OLT失败 返回字段
                    redis_oper.conn.set("%s_%s_startrun_signal" % (self.tnip, self.tnport), "fail", 10)
                    time.sleep(10)
                    continue
                else:
                    break

        try:
            result1 = self.tn.read_until(b'Username:', timeout=10)

        except Exception as e:
            # Connection reset by peer 的情况
            if "Connection reset by peer" in str(e):
                return False, "Connection reset by peer"

        self.tn.write(self.username.encode('ascii') + b'\n')
        # 等待Password出现后输入用户名，最多等待10秒
        result2 = self.tn.read_until(b'Password:', timeout=10)
        self.tn.write(self.password.encode('ascii') + b'\n')
        time.sleep(2)
        self.command_result = self.tn.read_very_eager().decode('ascii', errors='ignore')
        if self.command_result:
            if "% No username or bad password" in self.command_result:

                print("用户名或密码无效 %s" % (self.command_result))

                # 运行日志
                write_log(data=self.command_result, oltip=self.tnip, oltport=self.tnport, userrole=userrole)
                # data, oltip, oltport, level=None
                # write_log(data=self.command_result, oltip=self.tnip, oltport=self.tnport, userrole=userrole)
                # 人为操作  启动运行OLT失败 返回字段
                redis_oper.conn.set("%s_%s_startrun_signal" % (self.tnip, self.tnport), "fail", 10)
                return False, "用户名或密码无效"
            elif "#" in self.command_result:

                msg = "发送消息状态为：false"
                # 登录成功 ，发送信息
                if up_down_remind == "是":
                    # 正常登陆 还是 因为异常断开，重新登陆
                    redis_key = "%s_exception_connect" % (self.olt_id)
                    exception_connect = redis_oper.redis_get(redis_key)
                    # print("exception_connect",type(exception_connect))
                    # print("exception_connect",exception_connect)
                    # 正常登陆
                    olt_info_obj = OltInfo.objects.get(olt_id=self.olt_id)
                    olt_name = olt_info_obj.olt_name
                    wechat_group = olt_info_obj.remind_group
                    if exception_connect is None:
                        msg = "[%s]登陆 \n- 时间:%s\n- IP:%s\n登陆已成功！" % (olt_name, str(datetime.now())[:19], self.tnip)
                    # 上次断开连接了，重新恢复连接
                    else:
                        msg = "[%s]连接已恢复 \n- 时间:%s\n- IP:%s\n登陆已成功！" % (olt_name, str(datetime.now())[:19], self.tnip)
                        redis_oper.redis_del(redis_key)
                    # 发送微信  异步任务
                    sendTeam(msg, 'robot')

                # 删除上次意外断开 发送过信息的记号字段
                redis_oper.conn.delete("%s_%s_sendmsg_swich" % (self.tnip, self.tnport))
                write_log(data=msg, oltip=self.tnip, oltport=self.tnport, userrole=userrole)
                # 运行日志 data, oltip, oltport, level=None
                # write_log(data=self.command_result, oltip=self.tnip, oltport=self.tnport,userrole=userrole)
                # userrole=userrole)
                print("登录到OLT")
                return True, "登录成功"
            else:
                print("未知情况登陆失败：-> %s" % (str(self.command_result)))

                # 运行日志 和 错误日志 data, oltip, oltport, level=None
                write_log(data=self.command_result, oltip=self.tnip, oltport=self.tnport, level="error")
                # 人为操作  启动运行OLT失败 返回字段
                redis_oper.conn.set("%s_%s_startrun_signal" % (self.tnip, self.tnport), "fail", 10)
                return False, self.command_result
        else:
            print("登录失败")

            # 运行日志 和 错误日志 data, oltip, oltport, level=error,
            # write_log(data=self.command_result, oltip=self.tnip, oltport=self.tnport,
            write_log(data=self.command_result, oltip=self.tnip, oltport=self.tnport, level="error")
            # 人为操作  启动运行OLT失败 返回字段
            redis_oper.conn.set("%s_%s_startrun_signal" % (self.tnip, self.tnport), "fail", 10)
            return False, self.command_result

    # 基本配置
    def base_config(self, autosave, userrole=None):
        close_old_connections()
        self.tn.write('\n terminal length 0'.encode('ascii') + b'\n')
        redis_oper.conn.set("%s_%s_startrun_signal" % (self.tnip, self.tnport), 1, 10)
        redis_oper.conn.set("%s_%s_running" % (self.tnip, self.tnport), self.olt_id, 10)

        return True

    @property
    def onu_login(self):
        close_old_connections()
        while True:
            # 保存数据方式 分为主动保存和自动保存
            olt_obj = OltInfo.objects.get(olt_id=self.olt_id)
            olt_obj.host_status = '正常'
            olt_obj.save()
            print("保存数据方式: %s" % olt_obj.save_mode)
            # save_mode = "activesave"
            if olt_obj.save_mode == "activesave":
                print("%s OLT为主动保存方式" % (olt_obj.olt_name))
                # 主动保存 根据设置间隔
                # 应该执行保存命令的时间
                # save_time = r.conn.get("%s_save_time"%(self.olt_id))
                save_time = redis_oper.redis_get("%s_save_time" % (self.olt_id))
                print("redis save_time", save_time)
                print("self.olt_id", self.olt_id)
                if save_time is None:
                    save_time = datetime.now() - relativedelta(minutes=1)
                    redis_oper.conn.set("%s_save_time" % (self.olt_id), str(save_time)[:19])
                    print("None save_time", save_time)
                if isinstance(save_time, str):
                    save_time = datetime.strptime(save_time, "%Y-%m-%d %H:%M:%S")
                print("上次保存时间：%s" % save_time)
                if datetime.now() > save_time:
                    self.tn.write("save".encode('ascii') + b'\n' + b'\n')
                    save_hours = olt_obj.save_hours
                    while True:
                        # self.result = self.tn.read_until("数据保存完成".encode('GBK'), timeout=5).decode('GBK', errors='ignore')
                        time.sleep(3)
                        self.result = self.tn.read_very_eager().decode('GBK', errors='ignore')
                        # print("self.result", self.result)
                        echo_resutl = redis_oper.redis_get("%s_%s_echo" % (self.tnip, self.tnport))
                        if echo_resutl == "true":
                            redis_oper.conn.lpush("%s_%s_echo_result" % (self.tnip, self.tnport), self.result)
                            redis_oper.conn.lpush("%s_%s_echo_result" % (self.tnip, self.tnport),
                                                  str(datetime.now())[:19])

                        print("更新%s %s运行状态" % (self.tnip, self.tnport))
                        redis_oper.conn.set("%s_%s_running" % (self.tnip, self.tnport), self.olt_id, 10)
                        write_log(data=self.result, oltip=self.tnip, oltport=self.tnport)

                        time.sleep(2)

                        # 连接异常
                        if self.result is None:
                            return "exception"

                        # 查询mysql中保存olt的时间间隔
                        if "数据保存完成" in self.result:
                            # while True:
                            #     time.sleep(5)
                            #     self.result = self.tn.read_very_eager().decode('GBK', errors='ignore')
                            #     if self.result:
                            # save_time += relativedelta(minutes=2)   #测试数据
                            save_time += relativedelta(hours=save_hours)
                            redis_oper.conn.set("%s_save_time" % (self.olt_id),
                                                datetime.strftime(save_time, "%Y-%m-%d %H:%M:%S"))
                            break
                        elif "数据保存完全" in self.result:
                            # save_time += relativedelta(minutes=1)   #测试数据
                            save_time += relativedelta(hours=save_hours)
                            redis_oper.conn.set("%s_save_time" % (self.olt_id),
                                                datetime.strftime(save_time, "%Y-%m-%d %H:%M:%S"))
                            break
                        elif "系统正在加载" in self.result or "系统正忙" in self.result:
                            # save_time += relativedelta(minutes=1)   #测试数据
                            save_time += relativedelta(hours=save_hours)
                            redis_oper.conn.set("%s_save_time" % (self.olt_id),
                                                datetime.strftime(save_time, "%Y-%m-%d %H:%M:%S"))
                            break
                        elif "失败：系统正忙，请稍后再试" in self.result:
                            continue

                        elif "错误位于'^'所指的位置" in self.result:
                            print("SAVE command error-parameter", self.result)
                            write_log(data=self.result, oltip=self.tnip, oltport=self.tnport, level="error")
                            # 运行日志 和 错误日志
                            # write_log(data=self.result, oltip=self.tnip, oltport=self.tnport,

            # 保存OLT配置信息
            save_configuration = redis_oper.redis_get("%s_save_configuration" % (self.olt_id))
            if save_configuration:
                config_result = self.olt_configinfo()
                if config_result:
                    file_path = os.path.join(LOG_DIR, "%s_%s" % (self.tnip, self.tnport))
                    if not os.path.exists(file_path):
                        os.makedirs(file_path, mode=0o777, exist_ok=True)

                    filename = os.path.join(file_path, "%s_%s_config.txt" % (self.tnip, self.tnport))
                    with open(filename, "w") as f:
                        f.write("%s 配置信息" % (olt_obj.olt_name))
                        f.write("\n")
                        for i in config_result.splitlines()[5:-2]:
                            f.write(i)
                            f.write("\n")

                redis_oper.redis_del("%s_save_configuration" % (self.olt_id))

            if self.onu_set:
                # 运行日志
                msg = "%s:%s 中 集合：%s " % (self.tnip, self.tnport, self.onu_set)
                print(msg)
                #
                write_log(data=msg, oltip=self.tnip, oltport=self.tnport)
                onu_sn_redis = list(self.onu_set)
                if onu_sn_redis:
                    onu_sn_redis = onu_sn_redis[0]
                else:
                    onu_sn_redis = ""
                print("集合取出计费要求注册的ONT信息：", onu_sn_redis)
            else:
                # 存入
                # redis_oper.conn.lpush("%s_%s_billing_onu" % (oltip, oltport), SN)

                # 取出
                onu_sn_redis = redis_oper.conn.rpop("%s_%s_billing_onu" % (self.tnip, self.tnport))
                if onu_sn_redis:
                    onu_sn_redis = onu_sn_redis.decode()
                print("redis取出计费要求注册的ONT信息：", onu_sn_redis)
            print("onu_set集合 ", self.onu_set)
            # 注册GPON光猫-发现光猫
            time_start = time.time()
            gponList, gponFlag = self.getGponList()
            eponList, eponFlag = self.getEponList()
            if gponFlag == False and eponFlag == False:
                continue
            else:
                re_result = gponList + eponList
                # 正常自动注册ONT
                logmsg = "正常流程注册ONT,过滤无需自动注册的ONT--开始"
                print(logmsg)
                # 运行日志
                write_log(data=logmsg, oltip=self.tnip, oltport=self.tnport)
                # 计费发起的ONT批量迁移数据  除了端口过滤以外的所有光猫全部注册
                batchmigrate = redis_oper.redis_get("%s_%s_ONTbatchmigrate" % (self.tnip, self.tnport))
                re_result = self.filter_foreign_onu(re_result)
                frameid, slotid, board_port, onu_sn = self.filter_onu(olt_id=self.olt_id,
                                                                      onu_info_list=re_result)

                logmsg = "正常流程注册ONT,过滤无需自动注册的ONT--结束 (frameid:%s slotid:%s board_port:%s SN:%s)" % (
                    frameid, slotid, board_port, onu_sn)
                # print(logmsg)
                # 运行日志
                write_log(logmsg, self.tnip, self.tnport)
                try:
                    board_info_obj = BoardInfo.objects.get(olt_info_id=self.olt_id, slotid=slotid,
                                                           board_port=board_port)
                except Exception as e:
                    board_info_obj = BoardInfo.objects.get(olt_info_id=self.olt_id, default_data="Y")
                    print("异步任务，缺少板卡信息，使用默认数据注册ONU")
                    # OLT名称、板卡位置
                    logmsg = "OLT:%s,位置:0框%s槽%s口，无板卡数据,使用默认数据注册ONT SN:%s" % (
                        olt_obj.olt_name, slotid, board_port, onu_sn)
                    print(logmsg)
                    # 运行日志 和 错误日志
                    write_log(data=logmsg, oltip=self.tnip, oltport=self.tnport)
                    # 发送微信  异步任务
                    msg = "负责人请注意！！\nOLT:%s\n%s\n位置:0框%s槽%s口\n无板卡数据\n使用默认数据注册ONT\nSN:%s" % (
                        olt_obj.olt_name, self.tnip, slotid, board_port, onu_sn)
                    sendTeam(msg, 'robot')
                    # msgsend_wechat(msg=msg, wechat_group=CASE_GROUP_NAME)
                write_log(data=onu_sn, oltip=self.tnip, oltport=self.tnport)
                olt_name = olt_obj.olt_name

                # 异常信息提醒微信群
                abnormal_group = olt_obj.abnormal_group

                community_name = board_info_obj.community_name
                if community_name is None:
                    community_name = "未配置小区名称"
                wechat_group = board_info_obj.send_group
                if wechat_group is None:
                    wechat_group = olt_obj.remind_group
                    if wechat_group is None:
                        wechat_group = ''
                line_template = board_info_obj.line_template_gpon  # GPON线路模板
                business_template = board_info_obj.business_template_gpon  # GPON业务模板
                business_intimal = board_info_obj.business_intimal  # 业务内层
                business_outer = board_info_obj.business_outer  # 业务外层
                gemport = str(board_info_obj.gemport)

                # GPON 注册
                if onu_sn is not None and len(onu_sn) == 12:
                    logmsg = "进入GPON注册流程 开始"
                    print(logmsg)
                    # 运行日志
                    find_time = str(datetime.now())[:19]
                    write_log(data=logmsg, oltip=self.tnip, oltport=self.tnport)

                    gponlogin_finish, flow_result = self.gpon_flow(frameid=frameid,
                                                                   slotid=slotid,
                                                                   board_port=board_port,
                                                                   onu_sn=onu_sn,
                                                                   find_time=find_time,
                                                                   line_template_GPON=line_template,
                                                                   business_template_GPON=business_template,
                                                                   business_intimal=business_intimal,
                                                                   business_outer=business_outer,
                                                                   gemport=gemport)
                    logmsg = "进入GPON注册流程 结束"
                    print(logmsg)
                    # 运行日志
                    #
                    write_log(data=logmsg, oltip=self.tnip, oltport=self.tnport)
                    if gponlogin_finish == False:

                        if flow_result == "正在保存数据":
                            time.sleep(5)

                        # 用户执行退出
                        elif flow_result == "logout":
                            # 计费发起的注册ONT
                            if onu_sn_redis:
                                # 计费触发注册ONU标识删除
                                self.onu_set.discard(onu_sn_redis)
                                redis_oper.conn.set("%s_%s" % (self.olt_id, onu_sn_redis),
                                                    "failed-logout", 10)
                            break

                        elif flow_result == "失败: 序列码已经存在":
                            # 运行日志
                            logmsg = "失败: 序列码已经存在 删除 ONT SN:%s  开始" % (onu_sn)
                            #
                            write_log(data=logmsg, oltip=self.tnip, oltport=self.tnport)
                            gpondel_finish, flow_result = self.del_gpononu(onu_sn, wechat_group)
                            if gpondel_finish == "failed":
                                # 用户执行退出
                                if flow_result == "logout":
                                    # 运行日志
                                    logmsg = "失败: 序列码已经存在 删除 ONT SN:%s  删除过程中，用户执行OLT退出" % (onu_sn)
                                    write_log(data=logmsg, oltip=self.tnip, oltport=self.tnport)
                                    # 计费发起的注册ONT
                                    if onu_sn_redis:
                                        # 计费触发注册ONU标识删除
                                        self.onu_set.discard(onu_sn_redis)
                                        redis_oper.conn.set("%s_%s" % (self.olt_id, onu_sn_redis),
                                                            "failed-logout", 10)  # id + sn码
                                    break
                                elif flow_result == "result is None":
                                    # 运行日志
                                    logmsg = "失败: 序列码已经存在 删除 ONT SN:%s  删除过程中，命令返回结果为空" % (onu_sn)
                                    write_log(data=logmsg, oltip=self.tnip, oltport=self.tnport)
                                    #

                                    # 计费发起的注册ONT
                                    if onu_sn_redis:
                                        # 计费触发注册ONU标识删除
                                        self.onu_set.discard(onu_sn_redis)
                                        redis_oper.conn.set("%s_%s" % (self.olt_id, onu_sn_redis),
                                                            "failed-result is None", 10)  # id + sn码

                                    # 运行日志
                                    logmsg = "失败: 序列码已经存在 删除失败 ONT SN:%s  结束" % (onu_sn)
                                    write_log(data=logmsg, oltip=self.tnip, oltport=self.tnport)
                            else:
                                time.sleep(3)
                                # 保存 计费需要注册的ONT sn码  continue 以后能继续注册
                                if onu_sn_redis:
                                    self.onu_set.add(onu_sn_redis)
                                # 运行日志
                                logmsg = "失败: 序列码已经存在 删除 ONT SN:%s  结束" % (onu_sn)
                                write_log(data=logmsg, oltip=self.tnip, oltport=self.tnport)
                            # 删除GPON成功 ,返回重新注册
                            continue
                        elif "获取ONT号失败" in flow_result:
                            # 注册GPON中的异常情况
                            # 运行日志 和 错误日志
                            write_log(data=flow_result, oltip=self.tnip, oltport=self.tnport,
                                      level="error")
                            # 发送微信
                            # msg = "%s : %s" % (olt_name, flow_result)
                            msg = "%s : %s 获取ONT号失败" % (olt_name, onu_sn)
                            redis_result = redis_oper.redis_get("register_failed_%s" % onu_sn)
                            if redis_result is None:
                                sendTeam(msg, 'robot')
                                redis_oper.conn.set("register_failed_%s" % onu_sn, onu_sn, ex=60 * 60 * 2)
                            # msgsend_wechat(msg=msg, wechat_group=CASE_GROUP_NAME)
                        elif "端口下ONT已经达到最大数目" in flow_result:
                            # 注册GPON中的异常情况
                            # 运行日志 和 错误日志
                            write_log(data=flow_result, oltip=self.tnip, oltport=self.tnport,
                                      level="error")
                            # 发送微信
                            # msg = "%s : %s" % (olt_name, flow_result)
                            msg = "%s \n%s" % (olt_name, flow_result)
                            redis_result = redis_oper.redis_get("register_failed_%s" % onu_sn)
                            if redis_result is None:
                                sendTeam(msg, 'robot')
                                redis_oper.conn.set("register_failed_%s" % onu_sn, onu_sn, ex=60 * 60 * 2)
                        else:
                            # 注册GPON中的异常情况
                            # 运行日志 和 错误日志
                            #
                            write_log(data=flow_result, oltip=self.tnip, oltport=self.tnport,
                                      level="error")
                            failedcause = ""
                            for i in flow_result:
                                if "失败" in i:
                                    failedcause = i
                            if failedcause == "":
                                failedcause = flow_result
                            msg = "%s \nSN:%s 注册失败 \n%s" % (olt_name, onu_sn, failedcause)
                            # 发送微信
                            redis_result = redis_oper.redis_get("register_failed_%s" % onu_sn)
                            if redis_result is None:
                                sendTeam(msg, 'robot')
                                redis_oper.conn.set("register_failed_%s" % onu_sn, onu_sn, ex=60 * 60 * 2)
                            # msgsend_wechat(msg=msg, wechat_group=CASE_GROUP_NAME)

                        # 计费发起的注册ONT
                        if onu_sn_redis:
                            # 计费触发注册ONU标识删除
                            self.onu_set.discard(onu_sn_redis)
                            redis_oper.conn.set("%s_%s" % (self.olt_id, onu_sn_redis), "onu login failed",
                                                10)  # id + sn码

                        time.sleep(5)
                        continue

                    else:
                        ontid = flow_result
                        # 发送注册成功消息
                        # else:
                        msg = """设备名称:[{}] \n\n接入小区:{}\n\n机框位置:{}槽{}口{}序\n\nSN:{}\n\nVLAN信息:{}/{}\n\n装机时间:{}\n\n注册成功！\n""".format(
                            olt_name, community_name, slotid, board_port, ontid, onu_sn, business_outer,
                            business_intimal, find_time)
                        print(1)
                        sendTeam(msg, 'robot')
                        # 注册ONT信息保存mysql
                        Save_OntRecord(olt_id=self.olt_id,
                                       equipment=olt_name,
                                       community=community_name,
                                       olt_type="中兴GPON",
                                       register_type="注册",
                                       frameid=0,
                                       slotid=slotid,
                                       board_port=board_port,
                                       ont_num=ontid,
                                       sn=onu_sn,
                                       line_template=line_template,
                                       business_template=business_template,
                                       business_outer=business_outer,
                                       business_intimal=business_intimal,
                                       gemport=gemport,
                                       )
                        # 发送微信
                        print(2)
                        print("GPON注册流程耗时", time.time() - time_start)
                        # 运行日志
                        #
                        write_log(data=msg, oltip=self.tnip, oltport=self.tnport)
                        # 将sn码 保存至配置文件中，供计费调取使用
                        file_path = os.path.join(LOG_DIR, "%s_%s" % (self.tnip, self.tnport))
                        if not os.path.exists(file_path):
                            os.makedirs(file_path, mode=0o777, exist_ok=True)
                        filename = os.path.join(file_path, "%s_%s_config.txt" % (self.tnip, self.tnport))
                        with open(filename, "a") as f:
                            f.write("\n")
                            f.write(
                                'ont add {} {} sn-auth "{}" omci ont-lineprofile-id {} '.format(board_port,
                                                                                                ontid,
                                                                                                onu_sn,
                                                                                                line_template))
                            f.write("\n")

                        # 计费发起的注册ONT
                        if onu_sn_redis:
                            # 计费触发注册ONU标识删除
                            self.onu_set.discard(onu_sn_redis)
                            redis_oper.conn.set("%s_%s" % (self.olt_id, onu_sn_redis),
                                                "onu login succeed-%s槽%s口%s序" % (slotid, board_port, ontid),
                                                10)  # id + sn码
                            # return  True , msg
                elif onu_sn is not None and len(onu_sn) == 14:
                    logmsg = "进入EPON注册流程 开始"
                    print(logmsg)
                    # 运行日志
                    write_log(data=logmsg, oltip=self.tnip, oltport=self.tnport)
                    find_time = str(datetime.now())[:19]
                    gponlogin_finish, flow_result = self.epon_flow(frameid=frameid,
                                                                   slotid=slotid,
                                                                   board_port=board_port,
                                                                   onu_mac=onu_sn,
                                                                   find_time=find_time,
                                                                   line_template_EPON=line_template,
                                                                   business_template_EPON=business_template,
                                                                   business_intimal=business_intimal,
                                                                   business_outer=business_outer,
                                                                   gemport=gemport)
                    logmsg = "进入EPON注册流程 结束"
                    print(logmsg)
                    # 运行日志
                    #
                    write_log(data=logmsg, oltip=self.tnip, oltport=self.tnport)
                    if gponlogin_finish == False:

                        if flow_result == "正在保存数据":
                            time.sleep(5)

                        # 用户执行退出
                        elif flow_result == "logout":
                            # 计费发起的注册ONT
                            if onu_sn_redis:
                                # 计费触发注册ONU标识删除
                                self.onu_set.discard(onu_sn_redis)
                                redis_oper.conn.set("%s_%s" % (self.olt_id, onu_sn_redis),
                                                    "failed-logout", 10)
                            break

                        elif flow_result == "失败: 序列码已经存在":
                            # 运行日志
                            logmsg = "失败: 序列码已经存在 删除 ONT SN:%s  开始" % (onu_sn)
                            #
                            write_log(data=logmsg, oltip=self.tnip, oltport=self.tnport)
                            gpondel_finish, flow_result = self.del_gpononu(onu_sn, wechat_group)
                            if gpondel_finish == "failed":
                                # 用户执行退出
                                if flow_result == "logout":
                                    # 运行日志
                                    logmsg = "失败: 序列码已经存在 删除 ONT SN:%s  删除过程中，用户执行OLT退出" % (onu_sn)
                                    write_log(data=logmsg, oltip=self.tnip, oltport=self.tnport)
                                    # 计费发起的注册ONT
                                    if onu_sn_redis:
                                        # 计费触发注册ONU标识删除
                                        self.onu_set.discard(onu_sn_redis)
                                        redis_oper.conn.set("%s_%s" % (self.olt_id, onu_sn_redis),
                                                            "failed-logout", 10)  # id + sn码
                                    break
                                elif flow_result == "result is None":
                                    # 运行日志
                                    logmsg = "失败: 序列码已经存在 删除 ONT SN:%s  删除过程中，命令返回结果为空" % (onu_sn)
                                    write_log(data=logmsg, oltip=self.tnip, oltport=self.tnport)
                                    #

                                    # 计费发起的注册ONT
                                    if onu_sn_redis:
                                        # 计费触发注册ONU标识删除
                                        self.onu_set.discard(onu_sn_redis)
                                        redis_oper.conn.set("%s_%s" % (self.olt_id, onu_sn_redis),
                                                            "failed-result is None", 10)  # id + sn码

                                    # 运行日志
                                    logmsg = "失败: 序列码已经存在 删除失败 ONT SN:%s  结束" % (onu_sn)
                                    write_log(data=logmsg, oltip=self.tnip, oltport=self.tnport)
                            else:
                                time.sleep(3)
                                # 保存 计费需要注册的ONT sn码  continue 以后能继续注册
                                if onu_sn_redis:
                                    self.onu_set.add(onu_sn_redis)
                                # 运行日志
                                logmsg = "失败: 序列码已经存在 删除 ONT SN:%s  结束" % (onu_sn)
                                write_log(data=logmsg, oltip=self.tnip, oltport=self.tnport)
                            # 删除GPON成功 ,返回重新注册
                            continue
                        elif "获取ONT号失败" in flow_result:
                            # 注册GPON中的异常情况
                            # 运行日志 和 错误日志
                            write_log(data=flow_result, oltip=self.tnip, oltport=self.tnport,
                                      level="error")
                            # 发送微信
                            # msg = "%s : %s" % (olt_name, flow_result)
                            msg = "%s : %s 获取ONT号失败" % (olt_name, onu_sn)
                            redis_result = redis_oper.redis_get("register_failed_%s" % onu_sn)
                            if redis_result is None:
                                sendTeam(msg, 'robot')
                                redis_oper.conn.set("register_failed_%s" % onu_sn, onu_sn, ex=60 * 60 * 2)
                            # msgsend_wechat(msg=msg, wechat_group=CASE_GROUP_NAME)
                        elif "端口下ONT已经达到最大数目" in flow_result:
                            # 注册GPON中的异常情况
                            # 运行日志 和 错误日志
                            write_log(data=flow_result, oltip=self.tnip, oltport=self.tnport,
                                      level="error")
                            # 发送微信
                            # msg = "%s : %s" % (olt_name, flow_result)
                            msg = "%s \n%s" % (olt_name, flow_result)
                            redis_result = redis_oper.redis_get("register_failed_%s" % onu_sn)
                            if redis_result is None:
                                sendTeam(msg, 'robot')
                                redis_oper.conn.set("register_failed_%s" % onu_sn, onu_sn, ex=60 * 60 * 2)
                        else:
                            # 注册GPON中的异常情况
                            # 运行日志 和 错误日志
                            #
                            write_log(data=flow_result, oltip=self.tnip, oltport=self.tnport,
                                      level="error")
                            failedcause = ""
                            for i in flow_result:
                                if "失败" in i:
                                    failedcause = i
                            if failedcause == "":
                                failedcause = flow_result
                            msg = "%s \nSN:%s 注册失败 \n%s" % (olt_name, onu_sn, failedcause)
                            # 发送微信
                            redis_result = redis_oper.redis_get("register_failed_%s" % onu_sn)
                            if redis_result is None:
                                sendTeam(msg, 'robot')
                                redis_oper.conn.set("register_failed_%s" % onu_sn, onu_sn, ex=60 * 60 * 2)
                            # msgsend_wechat(msg=msg, wechat_group=CASE_GROUP_NAME)

                        # 计费发起的注册ONT
                        if onu_sn_redis:
                            # 计费触发注册ONU标识删除
                            self.onu_set.discard(onu_sn_redis)
                            redis_oper.conn.set("%s_%s" % (self.olt_id, onu_sn_redis), "onu login failed",
                                                10)  # id + sn码

                        time.sleep(5)
                        continue

                    else:
                        ontid = flow_result
                        # 发送注册成功消息
                        # else:
                        msg = """设备名称:[{}] \n\n接入小区:{}\n\n机框位置:{}槽{}口{}序\n\nSN:{}\n\nVLAN信息:{}/{}\n\n装机时间:{}\n\n注册成功！\n""".format(
                            olt_name, community_name, slotid, board_port, ontid, onu_sn, business_outer,
                            business_intimal, find_time)
                        print(1)
                        sendTeam(msg, 'robot')
                        # 注册ONT信息保存mysql
                        Save_OntRecord(olt_id=self.olt_id,
                                       equipment=olt_name,
                                       community=community_name,
                                       olt_type="中兴EPON",
                                       register_type="注册",
                                       frameid=0,
                                       slotid=slotid,
                                       board_port=board_port,
                                       ont_num=ontid,
                                       sn=onu_sn,
                                       line_template=line_template,
                                       business_template=business_template,
                                       business_outer=business_outer,
                                       business_intimal=business_intimal,
                                       gemport=gemport,
                                       )
                        # 发送微信
                        print(2)
                        print("EPON注册流程耗时", time.time() - time_start)
                        # 运行日志
                        #
                        write_log(data=msg, oltip=self.tnip, oltport=self.tnport)
                        # 将sn码 保存至配置文件中，供计费调取使用
                        file_path = os.path.join(LOG_DIR, "%s_%s" % (self.tnip, self.tnport))
                        if not os.path.exists(file_path):
                            os.makedirs(file_path, mode=0o777, exist_ok=True)
                        filename = os.path.join(file_path, "%s_%s_config.txt" % (self.tnip, self.tnport))
                        with open(filename, "a") as f:
                            f.write("\n")
                            f.write(
                                'ont add {} {} sn-auth "{}" omci ont-lineprofile-id {} '.format(board_port,
                                                                                                ontid,
                                                                                                onu_sn,
                                                                                                line_template))
                            f.write("\n")

                        # 计费发起的注册ONT
                        if onu_sn_redis:
                            # 计费触发注册ONU标识删除
                            self.onu_set.discard(onu_sn_redis)
                            redis_oper.conn.set("%s_%s" % (self.olt_id, onu_sn_redis),
                                                "onu login succeed-%s槽%s口%s序" % (slotid, board_port, ontid),
                                                10)  # id + sn码
                            # return  True , msg
            time.sleep(6)

    def filter_foreign_onu(self, onu_info_list):
        sn_list = [i[1] for i in onu_info_list]
        filter_sn_list = []
        for j in sn_list:
            try:
                dev = OmpDevice.objects.get(device_code=j)
                if dev.equipment_status == 0:
                    filter_sn_list.append(j)
            except Exception as e:
                print(e)
                device = OmpDevice.objects.create()
                device.device_code = j
                device.device_type = 1
                device.import_time = datetime.now()
                device.device_status = 0
                device.device_usage = 0
                device.receiver = '系统处理'
                device.org_id = 1
                device.equipment_status = 0
                device.save()
                msg = """中兴OLT存在未校验光猫:[{}] \n\n请联系相关人员校验后使用！\n""".format(j)
                sendTeam(msg, 'robot')
                filter_sn_list.append(j)
        return [i for i in onu_info_list if i[1] not in filter_sn_list]

    # 过滤光猫是否需要注册
    def filter_onu(self, olt_id, onu_info_list):
        """
        batchmigrate 计费发起的ONT批量迁移字段。计费专用
        """
        close_old_connections()

        sn_blacklist = list(SnBlacklist.objects.filter(olt_info_id=olt_id).values_list("sn", flat=True))
        # 运行日志
        if sn_blacklist:
            logmsg = "黑名单SN：%s，olt_id:%s" % (",".join(sn_blacklist), olt_id)
            print(logmsg)
        else:
            logmsg = "黑名单SN：无，olt_id:%s" % (olt_id)
            print(logmsg)

        if onu_info_list:
            # 随机获取列表下标
            subscript = random.randrange(0, len(onu_info_list))
            location_list = onu_info_list[subscript][0].split("/")
            frameid = location_list[0].split('_')[1]  # 框
            slotid = location_list[1]  # 槽
            board_port = location_list[2].split(':')[0]  # 板口
            onu_num = onu_info_list[subscript][1]
        else:
            frameid = None
            slotid = None
            board_port = None
            onu_num = None
        return frameid, slotid, board_port, onu_num

    def get_sn_info(self, onu_sn, onu_type, wechat_group=None, userrole=None):
        close_old_connections()
        # 运行日志
        logmsg = "获取 %s ONT SN:%s 原始位置  流程开始" % (onu_type, onu_sn)
        write_log(logmsg, self.tnip, self.tnport)
        if onu_type == "GPON":
            # GPON 获取sn码命令
            command = "display ont info by-sn {}".format(onu_sn)
        else:
            # EPON 获取mac地址命令
            command = "display ont info by-mac {}".format(onu_sn)
        self.result = self.commandResult_fun(command=command, userrole=userrole)

        olt_obj = OltInfo.objects.get(olt_id=self.olt_id)

        # 异常情况
        if self.result is None:
            return "failed", False, False, False
        # 不支持by-sn  by-mac 方式查询ONT信息
        elif "参数错误，错误位于'^'所指的位置" in self.result:
            board_result, command_result = self.board_info(scope="usable", userrole=userrole)
            # 所有可用板卡的信息 [['5', 'H807GPBD', '正常'], ['6', 'H807GPBD', '正常']]

            # OLT板卡信息
            board_port_info_list = []

            if board_result:
                for i in board_result:
                    # 获取某个板卡信息
                    # display board 0/i[0]
                    command_look = "display ont info 0 %s all" % (i[0])
                    ontinfo_result = self.ont_info(frameid=0, slotid=i[0], filtrate=False, userrole=userrole)

                    if isinstance(ontinfo_result, str):
                        if "失败: 该板不存在" in self.result:
                            logmsg = "%s: %s 返回信息---> %s" % (olt_obj.olt_name, command_look, self.result)
                            # 运行日志 和 错误日志
                            write_log(logmsg, self.tnip, self.tnport, None, 'error')
                            # 发送微信
                            sendTeam(logmsg, 'robot')
                            # msgsend_wechat(msg=logmsg, wechat_group=CASE_GROUP_NAME)
                            return "失败: 该板不存在", False, False, False
                        elif "失败: 端口不存在" in self.result:
                            logmsg = "%s:  %s 返回信息---> %s" % (olt_obj.olt_name, command_look, self.result)
                            # 运行日志 和 错误日志
                            write_log(logmsg, self.tnip, self.tnport, None, 'error')
                            # 发送微信
                            sendTeam(logmsg, 'robot')
                            # msgsend_wechat(msg=logmsg, wechat_group=CASE_GROUP_NAME)
                            return "失败: 端口不存在", False, False, False
                        elif "没有ONT可供查询" in self.result:
                            logmsg = "%s: %s 返回信息---> %s" % (olt_obj.olt_name, command_look, self.result)
                            # 运行日志 和 错误日志
                            write_log(logmsg, self.tnip, self.tnport, None, 'error')
                            # 发送微信
                            sendTeam(logmsg, 'robot')
                            # msgsend_wechat(msg=logmsg, wechat_group=CASE_GROUP_NAME)
                            return "没有ONT可供查询", False, False, False
                        elif "符合条件的ONT不存在" in self.result:
                            logmsg = "%s: %s 返回信息---> %s" % (olt_obj.olt_name, command_look, self.result)
                            # 运行日志 和 错误日志
                            write_log(logmsg, self.tnip, self.tnport, None, 'error')
                            # 发送微信
                            sendTeam(logmsg, 'robot')
                            # msgsend_wechat(msg=logmsg, wechat_group=CASE_GROUP_NAME)
                            return "符合条件的ONT不存在", False, False, False
                        elif "失败: 该框不存在" in self.result:
                            logmsg = "%s: %s 返回信息---> %s" % (olt_obj.olt_name, command_look, self.result)
                            # 运行日志 和 错误日志
                            write_log(logmsg, self.tnip, self.tnport, None, 'error')
                            # 发送微信
                            sendTeam(logmsg, 'robot')
                            # msgsend_wechat(msg=logmsg, wechat_group=CASE_GROUP_NAME)
                            return "失败: 该框不存在", False, False, False
                        elif "失败: 单板类型错误" in self.result:
                            logmsg = "%s: %s 返回信息---> %s" % (olt_obj.olt_name, command_look, self.result)
                            # 运行日志 和 错误日志
                            write_log(logmsg, self.tnip, self.tnport, None, 'error')
                            # 发送微信
                            sendTeam(logmsg, 'robot')
                            # msgsend_wechat(msg=logmsg, wechat_group=CASE_GROUP_NAME)
                            return "失败: 单板类型错误", False, False, False
                        else:
                            for info in ontinfo_result.splitlines():
                                if str(onu_sn) in info:
                                    re_reslut = [value for value in info.split("  ") if value != ""]
                                    if len(re_reslut) == 7:
                                        ont_num = re_reslut[0]
                                    else:
                                        ont_num = re_reslut[1]
                                    if "ONT总数为" in info:
                                        re_reslut = re.findall("端口([0-9].*)下,", info)
                                        frame, groove, ont_port = re_reslut[0].split("/")
                                        # 运行日志
                                        logmsg = "获取 %s ONT SN:%s 原始位置流程结束 （框:%s，槽:%s，端口:%s，ONT编号:%s）" % (
                                            onu_type, onu_sn, frame, groove, ont_port, ont_num)
                                        write_log(logmsg, self.tnip, self.tnport)
                                        return frame, groove, ont_port, ont_num

                            logmsg = "%s: 全局搜索 中 %s板查找 %s  没有位置信息 " % (olt_obj.olt_name, i[0], onu_sn)
                            print(logmsg)
                            # 运行日志 和 错误日志
                            write_log(logmsg, self.tnip, self.tnport, None, 'error')
                            # 发送微信
                            sendTeam(logmsg, 'robot')
                            # msgsend_wechat(msg=logmsg, wechat_group=CASE_GROUP_NAME)
                    else:
                        logmsg = "%s: 全局搜索 %s 位置失败: %s" % (olt_obj.olt_name, onu_sn, ontinfo_result)
                        print(logmsg)
                        # 运行日志 和 错误日志
                        write_log(logmsg, self.tnip, self.tnport, None, 'error')
                        # 发送微信
                        sendTeam(logmsg, 'robot')
                        # msgsend_wechat(msg=logmsg, wechat_group=CASE_GROUP_NAME)
                        return
            else:
                return "failed", False, False, False

        # 用户主动退出
        elif self.result == "logout":
            return "logout", False, False, False
        else:
            if "框/槽/端口" in self.result:
                self.re_result = re.findall("框/槽/端口 .*?: (.*?)\r\n.*?ONT编号 .*?: (.*?)\r\n", self.result)
                print("获取ONT的原位置返回信息：", self.result)
                if self.re_result is None:
                    # print("get sn fail:%s  \n  %s"%(command,self.result))
                    logmsg = "%s: None正则获取ONT(%s)原位置:%s -->返回信息 %s" % (
                        olt_obj.olt_name, onu_sn, self.re_result, self.result)
                    print(logmsg)
                    # 运行日志 和 错误日志
                    write_log(logmsg, self.tnip, self.tnport, None, 'error')
                    # 发送微信
                    sendTeam(logmsg, 'robot')
                    # msgsend_wechat(msg=logmsg, wechat_group=CASE_GROUP_NAME)
                if not self.re_result:
                    # print("get sn fail:%s  \n  %s"%(command,self.result))
                    logmsg = "%s: []正则获取ONT(%s)原位置:%s -->返回信息 %s" % (
                        olt_obj.olt_name, onu_sn, self.re_result, self.result)
                    print(logmsg)
                    # 运行日志 和 错误日志
                    write_log(logmsg, self.tnip, self.tnport, None, 'error')
                    # 发送微信
                    sendTeam(logmsg, 'robot')
                    # msgsend_wechat(msg=logmsg, wechat_group=CASE_GROUP_NAME)
                print("self.re_result-->", self.re_result)
                # #   ONT编号               : 0
                # # result1 = re.search("ONT编号               :( [0-9].*)*", result, flags=0).group()
                # result1 = re.search("ONT编号( .*: [0-9].*)*", result, flags=0).group()
                # ont_num = result1.split(":")[1].strip()
                # # print(ont_num)  # ont编号值
                #
                # #  框/槽/端口            : 0/2/1
                # # result2 = re.search("框/槽/端口            :( [0-9]*/[0-9]*/[0-9]*)", result, flags=0).group()
                # result2 = re.search("框/槽/端口( .*: [0-9]*/[0-9]*/[0-9]*)", result, flags=0).group()
                # result3 = result2.split(":")[1].strip()
                # # print("框/槽/端口-->", result3)
                location = self.re_result[0][0].split("/")

                # 运行日志
                logmsg = "获取 %s ONT SN:%s 原始位置  流程结束 （框:%s，槽:%s，端口:%s，ONT编号:%s）" % (
                    onu_type, onu_sn, location[0], location[1], location[2], self.re_result[0][1])
                write_log(logmsg, self.tnip, self.tnport)
                return location[0], location[1], location[2], self.re_result[0][1]  # 框 槽 口 ont编号
            # 没有得到ONT位置信息
            else:
                return self.result.splitlines()[1], False, False, False

    def del_gpononu(self, onu_sn, wechat_group=None, frameid=None, slotid=None, board_port=None, ontid=None,
                    userrole=None):
        close_old_connections()
        # 通过sn码删除ONU 先获取ONU位置和编号
        if not all([frameid, slotid, board_port, ontid]):
            frameid, slotid, board_port, ontid = self.get_sn_info(onu_sn, "GPON", wechat_group)

        # 异常情况
        if frameid == "result is None":
            return "failed", "result is None"

        # 用户主动退出
        if frameid == "logout":
            return "failed", "logout"

        olt_obj = OltInfo.objects.get(olt_ip=self.tnip, olt_port=self.tnport)
        if not all([frameid, slotid, board_port, ontid]):
            logmsg = "%s: 获取原ONT位置信息失败 frameid:%s slotid:%s board_port:%s ontid:%s" % (
                olt_obj.olt_name, frameid, slotid, board_port, ontid)
            print(logmsg)
            # 运行日志 和 错误日志
            write_log(logmsg, self.tnip, self.tnport, None, 'error')
            # 发送微信
            sendTeam(logmsg, 'robot')
            # msgsend_wechat(msg=logmsg, wechat_group=CASE_GROUP_NAME)
            return "failed", frameid
        # 查询虚拟端口号下的索引
        # display service-port port  0 / 2 / 0 ont 0
        command = 'display service-port port {}/{}/{} ont {}\n'.format(frameid, slotid, board_port, ontid)
        self.result = self.commandResult_fun(command=command, userrole=userrole)
        # 异常情况
        if self.result is None:
            return "failed", "result is None"

        elif "面向交换业务流列表" in self.result:
            print("index_result-->: %s" % self.result)
            # num = re.findall("-\r\n   (.*)\r\n  -", result)
            # print("---re_index---",num)
            # index = num[0].strip().split()[0]
            re_reslut = re.findall(" *([0-9].*?)gpon ", self.result)
            for i in re_reslut:
                command = "undo service-port %s" % i.split(" ")[0]
                self.commandResult_fun(command=command, userrole=userrole)

        elif "失败: 没有业务虚端口可以操作" in self.result:
            pass
        # 用户主动退出
        elif self.result == "logout":
            return "failed", "logout"
        else:
            # 运行日志 和 错误日志
            logmsg = "%s: %s 返回信息:%s" % (olt_obj.olt_name, command, self.result)
            write_log(logmsg, self.tnip, self.tnport, None, 'error')
            # 发送微信
            sendTeam(logmsg, 'robot')
            # msgsend_wechat(msg=logmsg, wechat_group=CASE_GROUP_NAME)
            return "failed", self.result

        interface_command = "interface gpon {}/{}".format(frameid, slotid)
        self.result = self.commandResult_fun(command=interface_command, userrole=userrole)

        # 异常情况
        if self.result is None:
            return "failed", "result is None"

        elif "失败: 单板类型错误" in self.result:
            print("del_onu GPON板卡类型错误：%s" % (self.result))
            logmsg = "%s: %s 返回信息:%s" % (olt_obj.olt_name, interface_command, self.result)
            # 运行日志 和 错误日志
            write_log(logmsg, self.tnip, self.tnport, None, 'error')
            # 发送微信
            sendTeam(logmsg, 'robot')
            # msgsend_wechat(msg=logmsg, wechat_group=CASE_GROUP_NAME)
            return "failed", self.result
        elif "失败: 该板不存在" in self.result:
            print("del_onu GPON该板不存在，进入失败:%s" % (self.result))
            logmsg = "%s: %s 返回信息:%s" % (olt_obj.olt_name, interface_command, self.result)
            # 运行日志 和 错误日志
            write_log(logmsg, self.tnip, self.tnport, None, 'error')
            # 发送微信
            sendTeam(logmsg, 'robot')
            # msgsend_wechat(msg=logmsg, wechat_group=CASE_GROUP_NAME)
            return "failed", self.result
        else:
            result_length = self.result.splitlines()
            # print("result_length", result_length)
            # 异常情况
            if self.result is None:
                return "failed", "result is None"

            # 用户执行退出
            if result_length[0] == "logout":
                return "failed", result_length[0]

            if result_length[1] != "":
                print("GPONinterface命令的未知情况：%s" % (self.result))
                # 运行日志 和 错误日志
                logmsg = "%s: %s 返回信息:%s" % (olt_obj.olt_name, interface_command, self.result)
                write_log(logmsg, self.tnip, self.tnport, None, 'error')
                # 发送微信
                sendTeam(logmsg, 'robot')
                # msgsend_wechat(msg=logmsg, wechat_group=CASE_GROUP_NAME)
                return "failed", self.result

            ontdel_command = 'ont delete {} {}'.format(board_port, ontid)
            self.result = self.commandResult_fun(command=ontdel_command, userrole=userrole)

            # 异常情况
            if self.result is None:
                return "failed", "result is None"
            # 用户主动退出
            elif self.result == "logout":
                result = "failed"
                cause = "logout"

            elif "可以被删除的ONT数目: 1, 成功数目: 1" in self.result:
                msg = """发现需要移机的光猫\n\n[{}]{}/{}/{}/{}序\n\nSN:{}\n\n移机成功,\n\n即将注册!\n\n""".format(olt_obj.olt_name,
                                                                                                frameid, slotid,
                                                                                                board_port, ontid,
                                                                                                onu_sn)
                print(msg)
                # 删除ONT信息保存mysql
                print(111)
                Save_OntRecord(olt_id=self.olt_id,
                               equipment=olt_obj.olt_name,
                               community=None,
                               olt_type="华为GPON",
                               register_type="删除",
                               frameid=0,
                               slotid=slotid,
                               board_port=board_port,
                               ont_num=ontid,
                               sn=onu_sn,
                               line_template=None,
                               business_template=None,
                               business_outer=None,
                               business_intimal=None,
                               gemport=None,
                               )
                # msg = """测试\n删除EPON\n{}\n{}\n{}/{}/{}""".format(onu_sn,frameid, slotid, board_port, ontid)
                # 运行日志
                print(222)
                write_log(msg, self.tnip, self.tnport)
                # 发送微信
                # print("wechat_group",wechat_group)
                if wechat_group:
                    sendTeam(msg, 'robot')
                # else:
                #     msgsend_wechat(msg=msg, wechat_group=CASE_GROUP_NAME)
                result = "succeed"
                cause = False

            elif "失败: 该配置对象存在业务虚端口" in self.result:
                msg = "%s: 失败: 该配置对象存在业务虚端口： %s 返回信息--> %s" % (olt_obj.olt_name, ontdel_command, self.result)
                print(msg)
                # 运行日志 和 错误日志
                write_log(msg, self.tnip, self.tnport, None, 'error')
                # 发送微信
                sendTeam(msg, 'robot')
                sendTeam(msg, 'robot')
                # msgsend_wechat(msg=msg, wechat_group=CASE_GROUP_NAME)

                result = "failed"
                cause = self.result
            else:
                msg = "删除ONT出现异常：{} -> {}".format(command, self.result)
                print(msg)
                msg = "%s: 删除ONT出现异常： %s 返回信息--> %s" % (olt_obj.olt_name, ontdel_command, self.result)
                # 运行日志 和 错误日志
                write_log(msg, self.tnip, self.tnport, None, 'error')
                # 发送微信
                sendTeam(msg, 'robot')
                sendTeam(msg, 'robot')
                # msgsend_wechat(msg=msg, wechat_group=CASE_GROUP_NAME)

                result = "failed"
                cause = self.result

            self.commandResult_fun(command="quit", userrole=userrole)

            return result, cause

    def del_epononu(self, onu_mac, wechat_group=None, frameid=None, slotid=None, board_port=None, ontid=None,
                    userrole=None):
        close_old_connections()
        # 通过sn码删除ONU 先获取ONU位置和编号
        if not all([frameid, slotid, board_port, ontid]):
            frameid, slotid, board_port, ontid = self.get_sn_info(onu_mac, "EPON", wechat_group)

        # 异常情况
        if frameid == "result is None":
            return "failed", "result is None"

        # 用户主动退出
        if frameid == "logout":
            return "failed", "logout"

        olt_obj = OltInfo.objects.get(olt_ip=self.tnip, olt_port=self.tnport)
        if not all([frameid, slotid, board_port, ontid]):
            logmsg = "%s: 获取原ONT位置信息失败 frameid:%s slotid:%s board_port:%s ontid:%s" % (
                olt_obj.olt_name, frameid, slotid, board_port, ontid)
            print(logmsg)
            # 运行日志 和 错误日志
            write_log(logmsg, self.tnip, self.tnport, None, 'error')
            # 发送微信
            sendTeam(logmsg, 'robot')
            # msgsend_wechat(msg=logmsg, wechat_group=CASE_GROUP_NAME)
            return "failed", frameid

        # 查询虚拟端口号下的索引
        # display service-port port  0 / 2 / 0 ont 0
        # display service-port epon  0 / 2 / 0 ont 0    特点：兼容老版本命令
        # command = 'undo service-port epon  {}/{}/{} ont {}\ny'.format(frameid, slotid, board_port, ontid)
        command = 'display service-port port {}/{}/{} ont {}\n'.format(frameid, slotid, board_port, ontid)
        self.result = self.commandResult_fun(command=command, userrole=userrole)
        print("command  self.result", self.result)
        # delEPON_command2 = 'y'
        # self.result = self.commandResult_fun(command=delEPON_command2, userrole=userrole)

        # 异常情况
        if self.result is None:
            return "failed", "result is None"
        # 用户主动退出
        elif self.result == "logout":
            return "failed", "logout"

        elif "错误位于'^'所指的位置" in self.result:
            delEPON_command1 = 'undo service-port epon  {}/{}/{} ont {}\ny'.format(frameid, slotid, board_port, ontid)
            self.result = self.commandResult_fun(command=delEPON_command1, userrole=userrole)
            # delEPON_command2 = 'y'
            # self.result = self.commandResult_fun(command=delEPON_command2, userrole=userrole)
            print("command_result删除EPON--->", self.result)
        else:
            if "面向交换业务流列表" in self.result:
                print("index_result-->:", self.result)
                # num = re.findall("-\r\n   (.*)\r\n  -", result)
                # print("---re_index---",num)
                # index = num[0].strip().split()[0]
                re_reslut = re.findall(" *([0-9].*?)epon ", self.result)
                for i in re_reslut:
                    command = "undo service-port %s" % i.split(" ")[0]
                    self.commandResult_fun(command=command, userrole=userrole)
            elif "失败: 没有业务虚端口可以操作" in self.result:
                pass
            else:
                logmsg = "%s: %s 返回信息:%s" % (olt_obj.olt_name, command, self.result)
                # 运行日志 和 错误日志
                write_log(logmsg, self.tnip, self.tnport, None, 'error')
                # 发送微信
                sendTeam(logmsg, 'robot')
                # msgsend_wechat(msg=logmsg, wechat_group=CASE_GROUP_NAME)

                return "failed", self.result

        interface_command = "interface epon {}/{}".format(frameid, slotid)
        self.result = self.commandResult_fun(command=interface_command, userrole=userrole)

        # 异常情况
        if self.result is None:
            return "failed", "result is None"

        elif "失败: 单板类型错误" in self.result:
            print("del_onu EPON板卡类型错误：%s" % (self.result))
            logmsg = "%s: %s 返回信息:%s" % (olt_obj.olt_name, interface_command, self.result)
            # 运行日志 和 错误日志
            write_log(logmsg, self.tnip, self.tnport, None, 'error')
            # 发送微信
            sendTeam(logmsg, 'robot')
            # msgsend_wechat(msg=logmsg, wechat_group=CASE_GROUP_NAME)
            return "failed", self.result

        elif "失败: 该板不存在" in self.result:
            print("del_onu EPON该板不存在，进入失败:%s" % (self.result))
            logmsg = "%s: %s 返回信息:%s" % (olt_obj.olt_name, interface_command, self.result)
            # 运行日志 和 错误日志
            write_log(logmsg, self.tnip, self.tnport, None, 'error')
            # 发送微信
            sendTeam(logmsg, 'robot')
            # msgsend_wechat(msg=logmsg, wechat_group=CASE_GROUP_NAME)
            return "failed", self.result

        else:
            result_length = self.result.splitlines()
            print("result_length", result_length)
            # 异常情况
            if self.result is None:
                return "failed", "result is None"

            # 用户执行退出
            if result_length[0] == "logout":
                return "failed", result_length[0]

            if result_length[1] != "":
                print("EPONinterface命令的未知情况：%s" % (self.result))
                # 运行日志 和 错误日志
                logmsg = "%s: %s 返回信息:%s" % (olt_obj.olt_name, interface_command, self.result)
                write_log(logmsg, self.tnip, self.tnport, None, 'error')
                # 发送微信
                sendTeam(logmsg, 'robot')
                # msgsend_wechat(msg=logmsg, wechat_group=CASE_GROUP_NAME)
                return "failed", self.result

            # ont delete 0 0
            ontdel_command = 'ont delete {} {}'.format(board_port, ontid)
            self.result = self.commandResult_fun(command=ontdel_command, userrole=userrole)
            # 异常情况
            if self.result is None:
                return "failed", "result is None"
            # 用户主动退出
            elif self.result == "logout":
                result = "failed"
                cause = "logout"

            elif "可以被删除的ONT数目: 1, 成功数目: 1" in self.result:

                msg = """发现需要移机的光猫\n\n[{}]{}/{}/{}/{}序\n\nMAC:{}\n\n移机成功,\n\n即将注册!\n\n""".format(olt_obj.olt_name,
                                                                                                 frameid, slotid,
                                                                                                 board_port, ontid,
                                                                                                 onu_mac)
                print(msg)
                # 删除ONT信息保存mysql
                print(1111)
                Save_OntRecord(olt_id=self.olt_id,
                               equipment=olt_obj.olt_name,
                               community=None,
                               olt_type="华为EPON",
                               register_type="删除",
                               frameid=0,
                               slotid=slotid,
                               board_port=board_port,
                               ont_num=ontid,
                               sn=onu_mac,
                               line_template=None,
                               business_template=None,
                               business_outer=None,
                               business_intimal=None,
                               gemport=None,
                               )

                # 运行日志
                print(2222)
                write_log(msg, self.tnip, self.tnport)
                # 发送微信
                if wechat_group:
                    sendTeam(msg, 'robot')
                # else:
                #     msgsend_wechat(msg=msg, wechat_group=CASE_GROUP_NAME)
                result = "succeed"
                cause = False

            elif "失败: 该配置对象存在业务虚端口" in self.result:
                msg = "%s: 失败: 该配置对象存在业务虚端口： %s 返回信息--> %s" % (olt_obj.olt_name, ontdel_command, self.result)
                print(msg)
                # 运行日志
                write_log(msg, self.tnip, self.tnport, None, 'error')
                # 发送微信
                sendTeam(msg, 'robot')
                sendTeam(msg, 'robot')
                # msgsend_wechat(msg=msg, wechat_group=CASE_GROUP_NAME)

                result = "failed"
                cause = self.result
            else:
                msg = "%s: 删除ONT出现异常： %s 返回信息--> %s" % (olt_obj.olt_name, ontdel_command, self.result)
                print(msg)
                # 运行日志
                write_log(msg, self.tnip, self.tnport, None, 'error')
                # 发送微信
                sendTeam(msg, 'robot')
                # msgsend_wechat(msg=msg, wechat_group=CASE_GROUP_NAME)

                result = "failed"
                cause = self.result

            self.commandResult_fun(command="quit", userrole=userrole)

            return result, cause

    def logout_host(self):
        """
        return  exception = 异常退出
                userrole = user 用户登录，直接退出
        """
        close_old_connections()
        self.tn.close()

    def gpon_flow(self, frameid, slotid, board_port, onu_sn, find_time, line_template_GPON, business_template_GPON,
                  business_intimal, business_outer, gemport):
        # olt_obj = OLT_Info.objects.get(id=self.olt_id)
        # 注册成功标识符
        gponlogin_finish = False

        # print("time sleep start")
        # time.sleep(5)
        # 查询注册第几个猫
        command = "show gpon onu state gpon-olt_{}/{}/{}".format(frameid, slotid, board_port)
        self.tn.write(command.encode('ascii') + b'\n')
        time.sleep(1)
        result = self.tn.read_very_eager().decode('ascii', errors='ignore')
        print(result.splitlines())
        if 'No related information to show' in result:
            num = 0
        else:
            num_result = result.splitlines()
            onu_list = num_result[3:num_result.__len__() - 2]
            onu_num_list = list()
            for i in onu_list:
                onu_num_list.append(i.split(' ')[0].split(':')[1])
            last_num = num_result[num_result.__len__() - 2].split('/')[1].split(' ')[0]
            flag = True
            for i in range(int(last_num)):
                if str(i + 1) in onu_num_list:
                    pass
                else:
                    if flag:
                        num = i
                        flag = False
            if flag:
                num = int(last_num)

        # 进入配置模式
        self.tn.write('con t'.encode('ascii') + b'\n')
        time.sleep(1)
        # 开始注册 interface gpon
        command = 'interface gpon-olt_{}/{}/{}'.format(frameid, slotid, board_port)
        self.tn.write(command.encode('ascii') + b'\n')
        time.sleep(1)
        self.result = self.tn.read_very_eager().decode('ascii', errors='jgnore')
        # 异常情况
        if self.result is None:
            return gponlogin_finish, "result is None"

        elif "Invalid input" in self.result:
            print("GPON该板不存在，进入失败:%s" % (self.result))
            # logmsg = "%s 返回信息---> %s" % (command, self.result)
            #
            # 发送微信
            # msgsend_wechat(msg=logmsg, wechat_group=olt_obj.remind_group)

            return gponlogin_finish, "{}框/{}槽 \n Command:{} \n {}".format(frameid, slotid, command, self.result)
        else:
            result_length = self.result.splitlines()
            print("result_length", result_length)
            if self.result is None:
                print("result == None")
        # go!!!
        ont_add = "onu {} type HW_HG8120C sn {}".format(int(num) + 1, onu_sn)
        self.tn.write(ont_add.encode('ascii') + b'\n')
        time.sleep(1)
        self.result = self.tn.read_very_eager().decode('ascii', errors='ignore')
        self.tn.write('exit'.encode('ascii') + b'\n')
        time.sleep(1)
        # 进入指定猫口
        ont_add_cat = 'interface gpon-onu_{}/{}/{}:{}'.format(frameid, slotid, board_port, int(num) + 1)
        self.tn.write(ont_add_cat.encode('ascii') + b'\n')
        time.sleep(1)
        ontid = None
        if self.result is None:
            return gponlogin_finish, "result is None"
        elif "已经达到最大数目" in self.result:

            self.commandResult_fun(command='quit')
            return gponlogin_finish, "ONT({})注册失败：{}框/{}槽/{}端口下ONT已经达到最大数目".format(onu_sn, frameid, slotid, board_port)
        ont_pro = "tcont 2 profile UP-1G"
        self.tn.write(ont_pro.encode('ascii') + b'\n')
        time.sleep(1)
        self.result = self.tn.read_very_eager().decode('ascii', errors='ignore')
        if self.result:
            self.tn.write('gemport 2 name gemport-2 unicast tcont 2'.encode('ascii') + b'\n')
            time.sleep(1)
            ont_ser = 'service-port 2 vport 2 user-vlan {} vlan {}'.format(line_template_GPON, business_template_GPON)
            self.tn.write(ont_ser.encode('ascii') + b'\n')
            time.sleep(1)
            self.tn.write('exit'.encode('ascii') + b'\n')
        else:
            pass

        # 进入远程下发模式
        ont_pon = "pon-onu-mng gpon-onu_{}/{}/{}:{}".format(frameid, slotid, board_port, int(num) + 1)
        self.tn.write(ont_pon.encode('ascii') + b'\n')
        time.sleep(1)
        self.result = self.tn.read_very_eager().decode('ascii', errors='ignore')
        if self.result:
            # 配置宽带业务流
            bus = 'service HSI type internet gemport 2 vlan {}'.format(business_template_GPON)
            self.tn.write(bus.encode('ascii') + b'\n')
            time.sleep(2)
            eth = 'vlan port eth_0/1 mode tag vlan {} priority 0'.format(business_outer)
            self.tn.write(eth.encode('ascii') + b'\n')
            time.sleep(1)
            eth2 = 'vlan port eth_0/2 mode tag vlan {} priority 0'.format(business_outer)
            self.tn.write(eth2.encode('ascii') + b'\n')
            time.sleep(1)
            self.tn.write(eth2.encode('ascii') + b'\n')
            time.sleep(1)
            self.tn.write('exit'.encode('ascii') + b'\n')
            time.sleep(1)
            self.tn.write('exit'.encode('ascii') + b'\n')
            time.sleep(1)
        else:
            pass
        gponlogin_finish = True
        return gponlogin_finish, int(num) + 1

    def epon_flow(self, frameid, slotid, board_port, onu_mac, find_time, line_template_EPON, business_template_EPON,
                  business_intimal, business_outer, gemport):
        # olt_obj = OLT_Info.objects.get(id=self.olt_id)
        # 注册成功标识符
        gponlogin_finish = False

        # print("time sleep start")
        # time.sleep(5)
        # 查询注册第几个猫

        command = "\n show epon onu state epon-olt_{}/{}/{}".format(frameid, slotid, board_port)
        self.tn.write(command.encode('ascii') + b'\n')
        time.sleep(3)
        result = self.tn.read_very_eager().decode('ascii', errors='ignore')
        # write_log()
        write_log(result, self.tnip, self.tnport, None, 'error')
        print(result.splitlines())
        if 'No related information to show' in result:
            num = 0
        else:
            num_result = result.splitlines()
            onu_list = [i for i in result.splitlines() if 'epon-onu_' in i]
            onu_num_list = list()
            for i in onu_list:
                onu_num_list.append(i.split(' ')[0].split(':')[1])
            last_num = num_result[num_result.__len__() - 2].split('/')[1].split(' ')[0]
            flag = True
            for i in range(int(last_num)):
                if str(i + 1) in onu_num_list:
                    pass
                else:
                    if flag:
                        num = i
                        flag = False
            if flag:
                num = int(last_num)

        # 进入配置模式
        self.tn.write('con t'.encode('ascii') + b'\n')
        time.sleep(1)
        # 开始注册 interface epon
        command = 'interface epon-olt_{}/{}/{}'.format(frameid, slotid, board_port)
        self.tn.write(command.encode('ascii') + b'\n')
        time.sleep(1)
        self.result = self.tn.read_very_eager().decode('ascii', errors='jgnore')
        # 异常情况
        if self.result is None:
            return gponlogin_finish, "result is None"

        elif "Invalid input" in self.result:
            print("EPON该板不存在，进入失败:%s" % (self.result))
            # logmsg = "%s 返回信息---> %s" % (command, self.result)
            #
            # 发送微信
            # msgsend_wechat(msg=logmsg, wechat_group=olt_obj.remind_group)

            return gponlogin_finish, "{}框/{}槽 \n Command:{} \n {}".format(frameid, slotid, command, self.result)
        else:
            result_length = self.result.splitlines()
            print("result_length", result_length)
            if self.result is None:
                print("result == None")
        # go!!!
        ont_add = "onu {} type ZTE-F420 mac {} ip-cfg static".format(int(num) + 1, onu_mac)
        self.tn.write(ont_add.encode('ascii') + b'\n')
        time.sleep(1)
        self.result = self.tn.read_very_eager().decode('ascii', errors='ignore')
        self.tn.write('exit'.encode('ascii') + b'\n')
        time.sleep(1)
        # 进入指定猫口
        ont_add_cat = 'interface epon-onu_{}/{}/{}:{}'.format(frameid, slotid, board_port, int(num) + 1)
        self.tn.write(ont_add_cat.encode('ascii') + b'\n')
        time.sleep(1)
        ontid = None
        if self.result is None:
            return gponlogin_finish, "result is None"
        elif "已经达到最大数目" in self.result:

            self.commandResult_fun(command='exit')
            return gponlogin_finish, "ONT({})注册失败：{}框/{}槽/{}端口下ONT已经达到最大数目".format(onu_mac, frameid, slotid, board_port)
        self.tn.write("admin enable".encode('ascii') + b'\n')
        time.sleep(1)
        self.tn.write("ems-autocfg-request disable".encode('ascii') + b'\n')
        time.sleep(1)
        self.tn.write(
            "sla upstream fixed 0 fixedpkt 64 assured 10000 maximum 1000000 maxburst 4500000 priority 0 vport 1".encode(
                'ascii') + b'\n')
        time.sleep(1)
        self.tn.write(
            "sla downstream fixed 0 fixedpkt 64 assured 10000 maximum 1000000 maxburst 4500000 priority 0 vport 1".encode(
                'ascii') + b'\n')
        time.sleep(1)
        self.tn.write("encrypt direction downstream  enable  vport 1".encode('ascii') + b'\n')
        time.sleep(1)
        self.tn.write("switchport mode trunk vport 1".encode('ascii') + b'\n')
        time.sleep(1)
        self.tn.write("switchport vlan {}  tag vport 1".format(business_outer).encode('ascii') + b'\n')
        time.sleep(1)
        self.tn.write('exit'.encode('ascii') + b'\n')
        time.sleep(1)
        # 进入远程下发模式
        ont_pon = "pon-onu-mng epon-onu_{}/{}/{}:{}".format(frameid, slotid, board_port, int(num) + 1)
        self.tn.write(ont_pon.encode('ascii') + b'\n')
        time.sleep(1)
        self.result = self.tn.read_very_eager().decode('ascii', errors='ignore')
        if self.result:
            # 配置宽带业务流
            bus = 'auto-config'
            self.tn.write(bus.encode('ascii') + b'\n')
            time.sleep(1)
            eth = 'vlan port eth_0/1 mode tag vlan {} priority 0'.format(business_outer)
            self.tn.write(eth.encode('ascii') + b'\n')
            time.sleep(1)
            eth2 = 'vlan port eth_0/2 mode tag vlan {} priority 0'.format(business_outer)
            self.tn.write(eth2.encode('ascii') + b'\n')
            time.sleep(1)
            self.tn.write(eth2.encode('ascii') + b'\n')
            time.sleep(1)
            self.tn.write('exit'.encode('ascii') + b'\n')
            time.sleep(1)
            self.tn.write('exit'.encode('ascii') + b'\n')
            time.sleep(1)
        else:
            pass
        gponlogin_finish = True
        return gponlogin_finish, int(num) + 1

    # 查看所有板卡
    def board_info(self, scope, userrole=None):
        self.tn.write('show card'.encode('ascii') + b'\n')
        time.sleep(2)
        self.result = self.tn.read_very_eager().decode('ascii', errors='ignore')
        if self.result is None:
            return False, "返回结果为空，连接异常"
        else:
            result = self.result
            pass
        print(result)
        if "Rack Shelf Slot" in result:
            board_info = []
            board_usable = []
            slot_list = []
            re_reslut = re.findall("(.*[0-9].*?)\r\n", self.result)
            print("re_reslut --->", re_reslut)
            for i in re_reslut:
                if 'Welcome' in i:
                    pass
                else:
                    board_info.append([value for value in i.split(" ") if value != ""])
                if 'GTGOG' in i and 'INSERVICE' in i:
                    board_usable.append([value for value in i.split(" ") if value != ""])
                if 'GTGOE' in i and 'INSERVICE' in i:
                    board_usable.append([value for value in i.split(" ") if value != ""])
                if "GTGOE" in i or "GTGOG" in i:
                    slot_list.append([value for value in i.split(" ") if value != ""])
            print(board_info)
            # 返回所有单板信息
            if scope == "all":
                return board_info, result
            elif scope == "usable":
                return board_usable, False
            elif scope == "num_list":
                # print("slot_list",slot_list)
                return slot_list, False
        else:
            print("show card 获取信息异常", result)
            # 运行日志 和 错误日志
            logmsg = "display board 0 获取信息异常: %s " % result
            write_log(logmsg, self.tnip, self.tnport)
            return False, result

    def board_one(self, board_num, scope=None):
        command = 'show card slot {}'.format(board_num)
        self.tn.write(command.encode('ascii') + b'\n')
        time.sleep(2)
        self.result = self.tn.read_very_eager().decode('ascii', errors='ignore')
        result = self.result
        if scope == 'board_info':
            return result
        boardPortInfo = list()
        board_name = [re.findall('.*', result)[4][15:22]]
        board_port_num = int(re.findall('.*', result)[6][15:18].strip())
        if board_name:
            if "GTGOG" in self.result:
                for i in range(1, board_port_num + 1):
                    command1 = 'show gpon onu state gpon-olt_1/{}/{}'.format(board_num, i)
                    self.tn.write(command1.encode('ascii') + b'\n')
                    time.sleep(2)
                    self.port_result = self.tn.read_very_eager().decode('ascii', errors='ignore')
                    port_resulf = re.findall('gpon-onu_1/{}/{}:[\d].*'.format(board_num, i), self.port_result)
                    for inx, val in enumerate(port_resulf):
                        boardPortInfo_dict = {}
                        if val != '':
                            if 'working' in val:
                                status = '在位'
                            else:
                                status = '不在位'

                            boardPortInfo_dict['num'] = inx
                            boardPortInfo_dict["portStatus"] = status
                            boardPortInfo.append(boardPortInfo_dict.copy())
                        else:
                            boardPortInfo_dict['num'] = inx
                            boardPortInfo_dict["portStatus"] = '不在位'

        return boardPortInfo

    # 获取板卡下某个端口信息
    def get_boardport_info(self, slotid, board_port, userrole=None):
        """
                display port state 0
        """
        command = 'show gpon olt config gpon-olt_1/{}/{}'.format(slotid, board_port)
        self.tn.write(command.encode('ascii') + b'\n')
        time.sleep(2)
        self.result = self.tn.read_very_eager().decode('ascii', errors='ignore')
        print(self.result)
        return self.result
        # board_command = "interface %s 0/%s" % (olt_type, slotid)
        # self.result = self.commandResult_fun(command=board_command, userrole=userrole)
        #
        # if self.result is None:
        #     return
        #
        # if "不存在" in self.result or "类型错误" in self.result:
        #     return self.result
        # board_command = "display port state %s" % (board_port)
        # self.result = self.commandResult_fun(command=board_command, userrole=userrole)
        # result = self.result
        # board_command = "quit"
        # self.result = self.commandResult_fun(command=board_command, userrole=userrole)
        # # print("self.result",result)
        # return result

    def ont_info(self, frameid, slotid=None, board_port=None, userrole=None, filtrate=None):
        """
        display ont info 0 7 2 all
        """
        command = "show gpon onu state gpon-olt_{}/{}/{}".format(frameid, slotid, board_port)
        # 没有ONT可供查询
        # 失败: 该板不存在
        # 失败: 端口不存在
        # 失败: 该框不存在
        # 失败: 单板类型错误
        # 符合条件的ONT不存在
        self.tn.write(command.encode('ascii') + b'\n')
        time.sleep(2)
        self.result = self.tn.read_very_eager().decode('ascii', errors='ignore')
        # 是否需要处理返回的信息
        if filtrate == True:
            result = re.findall("(.*[0-9].*?)\r\n", self.result)
            slist = []
            for i in result:
                zlist = []
                if 'gpon-onu' in i:
                    if 'HXMZ' in i:

                        zlist = i.split(' ')
                        zlist.pop()
                        slist.append([j for j in zlist if j != ""])
                    else:
                        zlist = i.split(' ')
                        slist.append([j for j in zlist if j != ""])
            command1 = "show gpon onu baseinfo gpon-olt_{}/{}/{}".format(frameid, slotid, board_port)
            self.tn.write(command1.encode('ascii') + b'\n\n\n')
            time.sleep(2)
            result = self.tn.read_very_eager().decode('ascii', errors='ignore')
            result = re.findall("(.*[0-9].*?)\r\n", result)
            dlist = []
            for i in result:
                zlist = []
                if 'gpon-onu' in i:
                    if 'HXMZ' in i:
                        zlist = i.split(' ')
                        zlist.pop()
                        dlist.append([j for j in zlist if j != ""])
                    else:
                        zlist = i.split(' ')
                        dlist.append([j for j in zlist if j != ""])
            for i in slist:
                for j in dlist:
                    if i[0] == j[0]:
                        i.append(j[3].split(':')[1])
            return slist
        else:
            return self.result

    # 获取ONT详细信息
    def sn_ont_info(self, fsp, get_content=None, userrole=None):
        """
                display ont info by-mac C070-094E-6B4E
                display ont info by-sn 5A544547C6B38F4A
                get_content="info"  获取框/槽/端口 编号 控制标志 运行标志 配置状态 匹配状态 信息
                get_content="state"  获取 详细信息  信息比较多
        """
        self.tn.write('terminal length 0'.encode('ascii') + b'\n')
        time.sleep(1)
        command = "show gpon onu detail-info {}".format(fsp)
        self.tn.write(command.encode('ascii') + b'\n')
        time.sleep(2)
        self.result = self.tn.read_very_eager().decode('ascii', errors='ignore')
        result_list = []
        if self.result:
            if "没有ONT可供查询" in self.result:
                result_list = "没有ONT可供查询"
            elif "符合条件的ONT不存在" in self.result:
                result_list = "符合条件的ONT不存在"
            elif "错误位于'^'所指的位置" in self.result:
                result_list = "OLT不支持 %s 命令" % (command)
            else:
                result = re.findall("(.*[0-9].*?)\r\n", self.result)
                print(result)
                for i in result:
                    print(i)
                    if 'HXMZ' in i:
                        continue
                    if 'Welcome' in i:
                        continue
                    else:
                        result_list.append(i)
        return result_list

    # 确认单板
    # board confirm {}/{}
    def confirm_slot(self, slotid, userrole=None):
        # slotid=slotid_list,operate = "确认单板"
        if len(slotid) > 1:
            confirm_command = "board confirm 0"
            self.result = self.commandResult_fun(command=confirm_command, userrole=userrole)

        elif len(slotid) == 1:
            confirm_command = "board confirm {}/{}".format(0, slotid[0]["num"])
            self.result = self.commandResult_fun(command=confirm_command, userrole=userrole)

        if self.result:
            return True, False
        else:
            return False, "连接异常"

    # 端口自动发现
    def port_autofind(self, board_type, slotid, port_num=None, userrole=None):
        if port_num is None:
            port_num = 16
        time22 = time.time()
        command = "interface {} {}/{}".format(board_type, 0, slotid)
        self.result = self.commandResult_fun(command=command, read_mode=4, userrole=userrole)
        print("time22", time.time() - time22)
        enable_auto_find = ""
        autofind_result = ""
        time11 = time.time()
        for i in range(port_num):
            enable_auto_find += "port {} ont-auto-find enable\n".format(i)
        self.result = self.commandResult_fun(command=enable_auto_find, userrole=userrole)
        # time.sleep(0.5)
        if self.result is None:
            return False, "连接异常"
        if "失败" in self.result:
            autofind_result = self.result
        enable_auto_find += "port 15 ont-auto-find enable"
        self.result = self.commandResult_fun(command=enable_auto_find, read_mode=10, userrole=userrole)
        print("开启端口发现 耗时：", time.time() - time11)
        time.sleep(1)
        command = "\n"
        self.commandResult_fun(command=command, read_mode=3, userrole=userrole)
        command = "quit"
        self.commandResult_fun(command=command, userrole=userrole)
        # command = "\n"
        # self.commandResult_fun(command=command, userrole=userrole)
        print("time33", time.time() - time22)
        return True, autofind_result

    # 用户调试模式 自定义输入命令
    def userinput_command(self, command, userrole=None):
        print("交互command", command)
        self.tn.write(command.encode('ascii') + b'\n')
        while True:
            time.sleep(2)
            userinput_result = self.tn.read_very_eager().decode('GBK', errors='ignore')
            print("交互模式信命令回执：", userinput_result)
            # userinput_result = self.tn.read_until(")#".encode('ascii'), timeout=2).decode('GBK', errors='ignore')
            # redis只存入调试信息内容  供websocket读取
            # redis_oper.conn.lpush("%s_%s_echo_resultdebugging" % (self.tnip, self.tnport), self.result)
            redis_oper.conn.lpush("%s_%s_%s_echo_resultdebugging" % (self.tnip, self.tnport, self.user_timestamp),
                                  userinput_result)

            if ")#" in userinput_result or "}:" in userinput_result:
                break
            elif userinput_result is None:
                break
            elif "任意键继续显示" in userinput_result:
                break

        # userinput_result = self.commandResult_fun(command=command, userrole=userrole)

    # OLT持续运行时间
    def get_runtime(self, userrole=None):
        command = "display sysuptime"
        self.result = self.commandResult_fun(command=command, userrole=userrole)
        return self.result

    def get_oltcurrenttime(self, userrole=None):
        command = "display time\n"
        self.result = self.commandResult_fun(command=command, userrole=userrole)
        return self.result

    # 获取上行板光衰
    def board_light_attenuation(self, board_num, board_type, userrole=None):
        command = "interface {} 0/{}".format(board_type, board_num)
        self.result = self.commandResult_fun(command=command, userrole=userrole)
        command = "display port ddm-info 0"
        result1 = self.commandResult_fun(command=command, userrole=userrole)
        command = "display port ddm-info 1"
        result2 = self.commandResult_fun(command=command, userrole=userrole)
        command = "quit"
        self.result = self.commandResult_fun(command=command, userrole=userrole)
        return result1 + result2

    # 获取ONT光衰
    def ont_light_attenuation(self, fsp, userrole=None):
        """display ont optical-info 0 2
        失败: ONT不在线
        MA5600T(config-if-epon-0/7)# """
        command = "show pon power onu-rx {}".format(fsp)
        self.tn.write(command.encode('ascii') + b'\n')
        time.sleep(1)
        result = self.tn.read_very_eager().decode('ascii', errors='ignore')
        result = re.findall("(.*[0-9].*?)\r\n", result)
        command = "show pon power onu-tx {}".format(fsp)
        self.tn.write(command.encode('ascii') + b'\n')
        time.sleep(1)
        result1 = self.tn.read_very_eager().decode('ascii', errors='ignore')
        result1 = re.findall("(.*[0-9].*?)\r\n", result1)
        result_list = []
        for i in result + result1:
            print(i)
            if 'show pon' in i:
                continue
            if 'Welcome' in i:
                continue
            else:
                result_list.append(i)

        return result_list

    # 获取ONT 上线、下线记录 10条
    def ontlogin_log(self, ont_type, frameid, slotid, board_port, ontNum, userrole=None):
        """
        interface gpon 0/5
        display ont register-info 0 1
        quit
         ---------------------------------------------------------------------
         索引编号            : 10
         认证方式            : SN认证
         ONT序列号           : 48575443A843DA52
         密   码             :
         ONT逻辑标识         :
         校验码              :
         ONT类型             : 120C
         上线时间            : 2021-01-03 13:55:40+08:00
         下线时间            : -
         下线原因            : -
         ---------------------------------------------------------------------
        """

        command = "interface {} {}/{}".format(ont_type, frameid, slotid)
        self.result = self.commandResult_fun(command=command, userrole=userrole)
        command = "display ont register-info {} {}".format(board_port, ontNum)
        result1 = self.commandResult_fun(command=command, userrole=userrole)
        command = "quit"
        self.result = self.commandResult_fun(command=command, userrole=userrole)
        return result1

    # 告警事件
    def alarm_history(self):
        self.tn.write('terminal length 0'.encode('ascii') + b'\n')
        time.sleep(1)
        self.tn.write('show alarm pool'.encode('ascii') + b'\n   ')
        time.sleep(1)
        self.result = self.tn.read_very_eager().decode('ascii', errors='ignore')
        self.result = re.findall("(.*[0-9].*?)\r\n", self.result)
        return self.result

    # 单板温度
    def board_temperature(self, userrole=None):
        self.tn.write('show temperature'.encode('ascii') + b'\n   ')
        time.sleep(2)
        self.result = self.tn.read_very_eager().decode('ascii', errors='ignore')
        self.result = re.findall("(.*[0-9].*?)\r\n", self.result)
        return self.result

    # 修改OLT系统时间
    def changge_systemtime(self, changetime, userrole=None):
        command = "time {}".format(changetime)
        self.result = self.commandResult_fun(command=command, userrole=userrole)
        return self.result

    # OLT配置信息
    def olt_configinfo(self, userrole=None):
        self.tn.write('terminal length 0'.encode('ascii') + b'\n')
        time.sleep(1)
        command = "show running-config"
        self.tn.write(command.encode('ascii') + b'\n')
        time.sleep(2)
        self.result = self.tn.read_very_eager().decode('ascii', errors='ignore')
        self.result = re.findall("(.*[0-9].*?)\r\n", self.result)
        return self.result

    # 获取OLT所有的ONT信息
    def all_ontinfo(self, userrole=None):
        command = "scroll 512"
        self.result = self.commandResult_fun(command=command, userrole=userrole)

        self.tn.write("display ont info 0 all".encode('ascii') + b'\n')
        all_result = ""
        while True:
            time.sleep(10)
            result = self.tn.read_very_eager().decode('GBK', errors='ignore')
            if "任意键继续显示" in result:
                all_result += result
                all_result += "\n"
                self.tn.write(" ".encode('ascii') + b'\n')
            else:
                all_result += result
                break

        return all_result

    def getGponList(self):
        # 注册GPON光猫-发现光猫
        print("发现光猫命令(show gpon onu uncfg)...")

        command = "show gpon onu uncfg"
        self.tn.write(command.encode('ascii') + b'\n\n\n')
        time.sleep(1)
        self.result = self.tn.read_very_eager().decode('ascii', errors='ignore')

        if "No related information to show" in self.result:
            print("%s:%s -- The automatically found ONUs do not exist(%s)" % (
                self.tnip, self.tnport, str(datetime.now())[:19]))
            # 检查是否有 ONT批量迁移 字段，并且ONT已经全部注册完毕
            batchmigrate = redis_oper.redis_get("%s_%s_ONTbatchmigrate" % (self.tnip, self.tnport))
            if batchmigrate:
                redis_oper.redis_del("%s_%s_ONTbatchmigrate" % (self.tnip, self.tnport))

            time.sleep(5)
            return [], False
        elif "OnuIndex" in self.result:
            # 获取GPON ONU信息
            rlist = re.findall("(.*[0-9].*?)\r\n", self.result)
            re_result_gpon = []
            for i in rlist:
                if 'Welcome' in i:
                    continue
                else:
                    zlist = []
                    if 'HXMZ' in i:
                        zlist = i.split(' ')
                        zlist.pop()
                    else:
                        zlist = i.split(' ')
                    re_result_gpon.append([j for j in zlist if j != ''])
            print(re_result_gpon)
            re_result = []
            for i in re_result_gpon:
                if 'gpon-onu_' in i[0]:
                    re_result.append(i)
            return re_result, True
        else:
            return [], False

    def getEponList(self):
        # 注册EPON光猫-发现光猫
        print("发现光猫命令(show onu unauthentication)...")

        command = "show onu unauthentication"
        self.tn.write(command.encode('ascii') + b'\n\n\n')
        time.sleep(1)
        self.result = self.tn.read_very_eager().decode('ascii', errors='ignore')

        if "No related information to show" in self.result:
            print("%s:%s -- The automatically found ONUs do not exist(%s)" % (
                self.tnip, self.tnport, str(datetime.now())[:19]))
            # 检查是否有 ONT批量迁移 字段，并且ONT已经全部注册完毕
            batchmigrate = redis_oper.redis_get("%s_%s_ONTbatchmigrate" % (self.tnip, self.tnport))
            if batchmigrate:
                redis_oper.redis_del("%s_%s_ONTbatchmigrate" % (self.tnip, self.tnport))

            time.sleep(5)
            return [], False
        else:
            # 获取EPON ONU信息
            res = re.findall("Onu Interface.*?SN", self.result, re.DOTALL)
            res = [i.split('\r\n') for i in res]
            print(res)
            re_result = []
            for i in res:
                re_result.append([i[0].split('   ')[2].replace(' ', ''), i[3].split(':')[1].replace(' ', '')])
            return re_result, True


# 监控OLT - 服务器之间网络状态
# def monitoring_state(self):
#     while True:
#         unique_identifier = redis_oper.redis_get("%s_%s_run_uniqueid" % (self.tnip, self.tnport))
#         if unique_identifier is None:
#             return
#         if not OLT_Info.objects.filter(id=self.olt_id).exists():
#             return
#         else:
#             # ping命令
#             pass


def hwolt_run(tnip, tnport, username, password):
    # OLT运行唯一标识符
    unique_identifier = redis_oper.redis_get("%s_%s_run_uniqueid" % (tnip, tnport))
    print(222)
    if unique_identifier is None:
        close_old_connections()
        obj = OltInfo.objects.get(olt_ip=tnip, olt_port=tnport)
        redis_oper.conn.set("%s_%s_run_uniqueid" % (tnip, tnport), "%s" % obj.id)

    while True:
        print("创建telnet连接")

        telnet_client = telnetip(tnip, tnport, username, password)
        print(1111)
        # 代表OLT已经启动 ，但是 是否启动成功 不一定
        redis_oper.conn.set("%s_%s_runstate" % (tnip, tnport), "true")
        print("登录OLT逻辑运行 开始")
        result, msg = telnet_client.login_host()
        print("登录OLT逻辑运行 完毕")
        print("result,msg", result, msg)
        result = telnet_client.base_config(1)
        # 登录成功
        if result:
            print("login succeed！{}:{}".format(tnip, tnport))

            exit_result = telnet_client.onu_login
            print("不注册了要退出", exit_result)
            # 运行日志
            logmsg = "%s:%s -->telnet_client.onu_login执行完毕，即将执行logout_host" % (tnip, tnport)
            write_log(logmsg, tnip, tnport)
            # 意外断开连接
            if exit_result == "exception":
                # redis 记录字段，异常断开连接
                redis_key = "%s_exception_connect" % (telnet_client.olt_id)
                redis_oper.conn.set(redis_key, "true")

                telnet_client.logout_host(exception=exit_result)
                continue
            # 静音退出
            elif exit_result == "silent_mode":
                telnet_client.logout_host(silent_mode=exit_result)
                break

            # 正常退出
            else:
                telnet_client.logout_host()
                break

        # 登录失败
        else:
            # 长时间断开连接，恢复后会报错
            if msg == "Connection reset by peer":
                continue
            else:
                # 运行日志 和 错误日志
                print("login failed！{}:{}".format(tnip, tnport))
                # write_log(data=msg, oltip=tnip, oltport=tnport,
                write_log(msg, tnip, tnport, None, 'error')
                redis_oper.conn.delete("%s_%s_run_uniqueid" % (tnip, tnport))
                break
